﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ProjTemp.Desktop.Common.ViewModel;
using System.ComponentModel.Composition;
using ProjTemp.Common.Logging;
using Microsoft.Practices.Prism.Regions;
using Microsoft.Practices.Prism.Events;
using Microsoft.Practices.ServiceLocation;
using MahApps.Metro;
using System.Windows.Media;
using Csla;
using ProjTemp.Desktop.Common;
using ProjTemp.Desktop.Common.App;
using Microsoft.Practices.Prism.Commands;
using ProjTemp.Desktop.Common.ResourceManagement;
using ProjTemp.Desktop.Common.Controls;
using System.ComponentModel;

namespace Mysoft.ServerMonitoring.OMKit.ViewModels
{
    [Export(typeof(ShellViewModel))]
    [PartCreationPolicy(CreationPolicy.Shared)]
    internal class ShellViewModel : VMBase<StatusInfo>
    {
        [ImportingConstructor]
        public ShellViewModel(ILogger logger, IRegionManager regionManager, IEventAggregator eventAggregator, IServiceLocator serviceLocator)
            :base(logger, regionManager, eventAggregator, serviceLocator)
        {
            this._logger.LogType = typeof(ShellViewModel);

            this.Model = new StatusInfo(serviceLocator.GetInstance<IResourceManage>()) { CurrentUserName = "xieyh", UserRoleName = "超级管理员", NetworkStatus = "已连接" };
            this.SaveCommand = new DelegateCommand(() => DoSave(), () => true);
            this.CancelCommand = new DelegateCommand(DoCancel, () => true);
        }

        private bool _isClientServersRegionVisible;
        public bool IsClientServersRegionVisible
        {
            get { return this._isClientServersRegionVisible; }
            set 
            {
                if (this._isClientServersRegionVisible != value)
                {
                    this._isClientServersRegionVisible = value;
                    this.RaisePropertyChanged(() => this.IsClientServersRegionVisible);
                }
            }
        }

        protected override StatusInfo DoSave()
        {
            ApplicationContext.LocalContext[StyleConst.DefaultTheme] = Model.SelectedTheme.Value;
            ApplicationContext.LocalContext[StyleConst.DefaultAccent] = Model.SelectedAccent.Value;
            (AppBase.Current as AppBase).ChangeTheme();
            App.Current.Resources[StyleConst.BusyIndicatorTypeKey] = Model.SelectedIndicatorType.Value;
            var resourceManager = this._serviceLocator.GetInstance<IResourceManage>();
            resourceManager.SetDefaultAspect(DesktopConst.LanguageResourceSubject, Model.SelectedLanguage.Value as string ?? "zh-CN" );
            resourceManager.ApplyToResourceDictionary(AppBase.Current.Resources);
            Model.LoadData();

            return base.DoSave();
        }
    }

    internal class StatusInfo : INotifyPropertyChanged
    {
        public string CurrentUserName {get; set;}
        public string UserRoleName {get; set;}
        public string NetworkStatus {get; set;}

        public IResourceManage ResourceManager { get; set; }

        public List<NameValue> Themes { get; set; }
        public List<NameValue> Accents { get; set; }
        public List<NameValue> IndicatorTypes { get; set; }
        public List<NameValue> SupportLanguages { get; set; }
        public NameValue SelectedAccent { get; set; }
        public NameValue SelectedTheme { get; set; }
        public NameValue SelectedIndicatorType { get; set; }
        public NameValue SelectedLanguage { get; set; }

        public StatusInfo(IResourceManage resourceManager)
        {
            this.ResourceManager = resourceManager;
            this.LoadData();
        }

        public void LoadData()
        {
            this.Themes = new List<NameValue>();
            this.Themes.Add(new NameValue() { Name = ResourceManager.GetLang(string.Concat(StyleConst.Prefix_Res_Global_Theme, "Light")), Value = "Light", Tag = new SolidColorBrush(Colors.White) });
            this.Themes.Add(new NameValue() { Name = ResourceManager.GetLang(string.Concat(StyleConst.Prefix_Res_Global_Theme, "Dark")), Value = "Dark", Tag = new SolidColorBrush(Colors.Black) });
            this.NotifyPropertyChanged("Themes");
            this.SelectedTheme = this.Themes.First(t => t.Value == ApplicationContext.LocalContext[StyleConst.DefaultTheme]);
            this.NotifyPropertyChanged("SelectedTheme");

            this.Accents = ThemeManager.DefaultAccents
                                .Select(a => new NameValue() { Name = ResourceManager.GetLang(string.Concat(StyleConst.Prefix_Res_Global_Accent, a.Name)), Value = a.Name, Tag = a.Resources["AccentColorBrush"] as Brush })
                                .ToList();
            this.NotifyPropertyChanged("Accents");
            this.SelectedAccent = this.Accents.First(a => a.Value == ApplicationContext.LocalContext[StyleConst.DefaultAccent]);
            this.NotifyPropertyChanged("SelectedAccent");

            this.IndicatorTypes = new List<NameValue>();
            this.IndicatorTypes.Add(new NameValue() { Name = ResourceManager.GetLang(string.Concat(StyleConst.Prefix_Res_Global_Indicator, BusyIndicatorType.Line.ToString())), Value = BusyIndicatorType.Line });
            this.IndicatorTypes.Add(new NameValue() { Name = ResourceManager.GetLang(string.Concat(StyleConst.Prefix_Res_Global_Indicator, BusyIndicatorType.Ring.ToString())), Value = BusyIndicatorType.Ring });
            this.IndicatorTypes.Add(new NameValue() { Name = ResourceManager.GetLang(string.Concat(StyleConst.Prefix_Res_Global_Indicator, BusyIndicatorType.Bar.ToString())), Value = BusyIndicatorType.Bar });
            this.NotifyPropertyChanged("IndicatorTypes");
            var indicatorType = BusyIndicatorType.Line;
            if(App.Current.Resources[StyleConst.BusyIndicatorTypeKey] != null && App.Current.Resources[StyleConst.BusyIndicatorTypeKey] is BusyIndicatorType)
                indicatorType = (BusyIndicatorType)App.Current.Resources[StyleConst.BusyIndicatorTypeKey];
            this.SelectedIndicatorType = this.IndicatorTypes.First(i => (BusyIndicatorType)i.Value == indicatorType);
            this.NotifyPropertyChanged("SelectedIndicatorType");

            this.SupportLanguages = new List<NameValue>();
            this.SupportLanguages.Add(new NameValue() { Name = ResourceManager.GetLang(string.Concat(StyleConst.Prefix_Res_Global_Language, "SimChinese")), Value = "zh-CN" });
            this.SupportLanguages.Add(new NameValue() { Name = ResourceManager.GetLang(string.Concat(StyleConst.Prefix_Res_Global_Language, "English")), Value = "en-US" });
            this.NotifyPropertyChanged("SupportLanguages");
            this.SelectedLanguage = this.SupportLanguages.First(l => string.Compare((string)l.Value, ResourceManager.GetDefaultAspect(DesktopConst.LanguageResourceSubject), true) == 0);
            this.NotifyPropertyChanged("SelectedLanguage");   
        }

        private void NotifyPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }

    public class NameValue : INotifyPropertyChanged
    {
        private string _name;
        private object _value;
        private object _tag;

        public string Name 
        {
            get { return this._name; }
            set { this._name = value; this.NotifyPropertyChanged("Name"); }
        }
        public object Value
        {
            get { return this._value; }
            set { this._value = value; this.NotifyPropertyChanged("Value"); }
        }
        public object Tag
        {
            get { return this._tag; }
            set { this._tag = value; this.NotifyPropertyChanged("Tag"); }
        }

        private void NotifyPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }
}
